package com.martin.lib_base.common

import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.RecyclerView
import com.martin.lib_base.annotation.ItemData
import com.martin.lib_base.base.BaseViewHolder
import com.martin.lib_base.bean.SimpleTypeBean
import com.martin.lib_base.interfaces.IAdapter
import com.martin.lib_base.interfaces.IItemData
import com.martin.lib_base.interfaces.ITypeBean
import com.martin.lib_base.interfaces.IOnItemClickListener
import com.martin.lib_base.interfaces.IRelease
import com.martin.lib_base.ktx.getLifecycleOwner
import com.martin.lib_base.utils.ReleaseUtil
import com.martin.lib_base.utils.releaseForLifecycle
import kotlinx.coroutines.flow.MutableStateFlow
import kotlin.reflect.KParameter

/**
 * @author：Houge
 * @date：2022/11/11
 * @desc：通用RecyclerView的适配器
 */
class CommonAdapter(
    // 上下文对象
    val context: Context,
    // 视图持有者class列表
    holderClassList: List<Class<out BaseViewHolder<*, out ViewDataBinding>>>
) : RecyclerView.Adapter<BaseViewHolder<*, out ViewDataBinding>>(), IAdapter, IOnItemClickListener,
    IRelease {

    var count : Int = 0

    //数据列表
    val items = arrayListOf<Any>()

    //布局加载器
    private val _inflater: LayoutInflater by lazy {
        LayoutInflater.from(context)
    }

    //数据状态
    private val _dataState = MutableStateFlow(STATE_EMPTY)

    //条目点击监听列表
    private val _itemClickListenerList = arrayListOf<IOnItemClickListener>()

    //类型map
    private val _typeMap =
        mutableMapOf<IItemData, Class<out BaseViewHolder<*, out ViewDataBinding>>>()

    init {
        /*
            遍历视图持有者class,获取ItemData数据
         */
        holderClassList.forEach {
            //校验是否被注解
            val annotation = (it.getAnnotation(ItemData::class.java)
                ?: throw NullPointerException("ViewHolder必须被[ItemData]注解"))

            //校验并获取无参构造函数
            val kFunction = annotation.itemDataClass.constructors.singleOrNull { const ->
                const.parameters.all(
                    KParameter::isOptional
                )
            } ?: throw IllegalArgumentException("[IItemData]必须要有无参构造方法")
            //构建条目数据对象
            val itemData: IItemData = kFunction.callBy(emptyMap())
            //将数据对象与类保存
            _typeMap[itemData] = it
        }

        // 监听生命周期,销毁时释放资源
        releaseForLifecycle(context.getLifecycleOwner())
    }

    /**
     * 添加点击事件监听
     */
    fun addOnItemClickListener(listener: IOnItemClickListener) {
        _itemClickListenerList.add(listener)
    }

    /**
     * 移除点击事件监听
     */
    fun removeOnItemClickListener(listener: IOnItemClickListener) {
        _itemClickListenerList.remove(listener)
    }

    /**
     * 条目点击事件触发
     */
    override fun onItemClick(position: Int, type: Int) {
        _itemClickListenerList.forEach { it.onItemClick(position, type) }
    }

    /**
     * 创建ViewHolder
     */
    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): BaseViewHolder<*, out ViewDataBinding> {
        // 获取类型对应的条目数据
        val itemData = _typeMap.keys.find { it.getItemType() == viewType }
            ?: throw NullPointerException("未找到 $viewType 对应类型的ViewHolder")
        // 获取ViewHolder的Class
        val holderClass = _typeMap[itemData]!!
        // 加载布局
        val view = _inflater.inflate(itemData.getItemLayoutId(), parent, false)
        // ViewHolder初始化
        val viewHolder = holderClass.getConstructor(View::class.java).newInstance(view)
        // 通知ViewHolder创建成功
        viewHolder.onCreateViewHolder()

        return viewHolder
    }

    /**
     * 绑定ViewHolder
     */
    override fun onBindViewHolder(holder: BaseViewHolder<*, out ViewDataBinding>, position: Int) {
        // 通知ViewHolder释放资源
        holder.release()
        // 绑定事件通知
        holder.onBindViewHolder(position, getItem(position))
    }

    /**
     * 刷新数据
     * null数据会导致数据清空,开发者自己决定是否执行清空逻辑
     */
    @SuppressLint("NotifyDataSetChanged")
    override fun refresh(list: List<Any>?) {
        beforeHandleData()

        (list ?: listOf()).let {
            releaseItems()
            items.clear()
            items.addAll(it)
            notifyDataSetChanged()
        }

        afterHandleData()
    }

    /**
     * 加载更多数据
     */
    override fun loadMore(list: List<Any>?, index: Int) {
        beforeHandleData()

        if (list.isNullOrEmpty()) {
            //空数据不处理
            return
        }
        //添加数据前的列表长度
        val oldSize = items.size
        if (index in 0 until oldSize) {
            items.addAll(index, list)
            notifyItemRangeInserted(index, list.size)
        } else {
            items.addAll(list)
            notifyItemRangeInserted(oldSize, list.size)
        }

        afterHandleData()
    }

    /**
     * 移除单个数据
     */
    override fun removeItem(index: Int) {
        beforeHandleData()

        val oldSize = items.size
        if (index in 0 until oldSize) {
            (items[index] as? IRelease)?.release()
            items.removeAt(index)
            notifyItemRemoved(index)
        }

        afterHandleData()
    }

    /**
     * 添加单个数据
     */
    override fun addItem(item: Any, index: Int) {
        beforeHandleData()

        if (index in 0 until items.size) {
            items.add(index, item)
            notifyItemInserted(index)
        } else {
            items.add(item)
            notifyItemInserted(items.size - 1)
        }

        afterHandleData()
    }

    /**
     * 在操作数据之前
     * 处理空列表的逻辑
     */
    private fun beforeHandleData() {
        //不是空数据状态,则跳出处理
        if (_dataState.value == STATE_EMPTY && items.isNotEmpty()) {
            items.clear()
        }
    }

    /**
     * 操作数据之后
     */
    private fun afterHandleData() {
        val empty = items.isEmpty()
        _dataState.value = if (empty) STATE_EMPTY else STATE_COMMON
        //当数据不为空 , 或者没有设置空数据ViewHolder时,跳出处理
        if (!empty || _typeMap.keys.find { it.getItemType() == ITypeBean.ITEM_TYPE_EMPTY } == null) {
            return
        }

        //添加一条空数据类型
        items.add(SimpleTypeBean(ITypeBean.ITEM_TYPE_EMPTY))
        //通知插入了一条信息
        notifyItemInserted(0)
    }

    /**
     * 获取条目数据
     */
    fun getItem(position: Int): Any? {
        return if (items.size > position) items[position] else null
    }

    /**
     * 获取数据数量
     */
    override fun getItemCount(): Int {
        return if(count == 0) items.size else count
    }

    fun setItemCount(count : Int){
        this.count = count
    }

    /**
     * 获取条目类型
     */
    override fun getItemViewType(position: Int): Int {
        val item = getItem(position)
        if (item != null && item is ITypeBean) {
            return item.itemType
        }
        return super.getItemViewType(position)
    }

    /**
     * 释放资源
     */
    override fun release() {
        ReleaseUtil.release(this)
        releaseItems()
        // 清空点击监听
        _itemClickListenerList.clear()
        // 清空类型映射
        _typeMap.clear()
    }

    /**
     * 释放条目数据
     */
    private fun releaseItems() {
        items
            .filterIsInstance<IRelease>()
            .forEach { it.release() }
        // 清空数据
        items.clear()
    }

    companion object {
        /* 数据状态 */

        //空数据状态
        const val STATE_EMPTY = -1

        //通常状态
        const val STATE_COMMON = 0
    }

}